package org.readium.r2.testapp.catalogs

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import org.readium.r2.opds.OPDS1Parser
import org.readium.r2.opds.OPDS2Parser
import org.readium.r2.shared.opds.ParseData
import org.readium.r2.shared.publication.Publication
import org.readium.r2.shared.util.AbsoluteUrl
import org.readium.r2.shared.util.Try
import org.readium.r2.shared.util.http.HttpRequest
import org.readium.r2.testapp.data.model.Catalog
import org.readium.r2.testapp.data.model.Vocabulary
import org.readium.r2.testapp.utils.EventChannel
import timber.log.Timber

class WordBookViewModel(application: Application) : AndroidViewModel(application) {

    val channel = EventChannel(Channel<Event>(Channel.BUFFERED), viewModelScope)

    sealed class Event {

        object EndOfList : Event()

        object StartOfList : Event()

        object EmptyList : Event()
    }

    private val _wordList = MutableLiveData<List<Vocabulary>>()
    val wordList: LiveData<List<Vocabulary>> get() = _wordList

    private val _currentIndex = MutableLiveData<Int>()
    val currentIndex: LiveData<Int> get() = _currentIndex

    val nowWord = MediatorLiveData<Vocabulary>().apply {
        addSource(wordList) {
            value = wordList.value?.getOrNull(currentIndex.value ?: 0)
        }
        addSource(currentIndex) {
            value = wordList.value?.getOrNull(currentIndex.value ?: 0)
        }
    }

    private val app = getApplication<org.readium.r2.testapp.Application>()

    fun updateWordList() = viewModelScope.launch {
        Timber.tag("WordBookViewModel").d("Updating word list")

        app.vocabularyRepository.getAllVocabularyMarked().collect {
            _wordList.value = it
            _currentIndex.value = it.size.coerceAtMost(1)
        }

        Timber.tag("WordBookViewModel").d("The value of wordlist size is: ${wordList.value?.size ?: 0}")
    }

    fun indexForward() {
        if ((_currentIndex.value ?: -1) == (_wordList.value?.size ?: 0) - 1) {
            channel.send(Event.EndOfList)
            return
        }
        _currentIndex.value = (_currentIndex.value ?: -1) + 1
    }

    fun indexBackward() {
        if ((_currentIndex.value ?: 0) == 0) {
            channel.send(Event.StartOfList)
            return
        }
        _currentIndex.value = (_currentIndex.value ?: 0) - 1
    }

    fun markVocabulary(mark: Boolean) = viewModelScope.launch {
        _wordList.value?.getOrNull(_currentIndex.value ?: 0)?.let {
            it.isMarked = mark
            app.vocabularyRepository.markVocabulary(it.entry, mark)
        }
    }
}